<?php
/**
 * 
 * +------------------------------------------------------------+
 * @category Helper 
 * +------------------------------------------------------------+
 * 框架内置辅助功能类库
 * +------------------------------------------------------------+
 *
 * @author anzai <236049524@qq.com>
 * @copyright http://www.judianyun.com 2013
 * @version 1.0
 *
 * Modified at : 2013-2-16 17:06:04
 *
 */
class Helper extends Base {
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name F
	 * +------------------------------------------------------------+
	 * 创建获取读取缓存文件
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param  $name  文件名
	 * @param  $data 写入缓存的值，为false时，表示读取缓存
	 * @param  $path  存储路径，默认存放在临时文件DATA_DIR目录下的temp子目录下
	 * @param  $cache_suffix 缓存文件名后缀
	 * @param  $filter 是否过滤空格
	 * 
	 * @return 写入成功返回true
	 *
	 */
	static public function F($name, $data = false, $path = null, $suffix='_cache', $filter=true){
		$path = $path === null ? TEMP_PATH . 'Cache' . DIRECTORY_SEPARATOR : $path;
		
		$cacheFile = $path . $name . $suffix . '.php';
		if ($data === false){
		    if (is_file($cacheFile)) $data = require $cacheFile;
			else $data = false;
			
			return $data;
		}
		
		$path = dirname($cacheFile) . DS;
		
		if(!is_dir($path)){
		    self::mkdir($path);
		}
		
		$content = '<?php'."\n/".'/created time：'.date('Y-m-d H:i:s')."\n";
		$content .= 'defined("APP_NAME") or exit(\'No permission resources.\');'."\n";
		
		if (is_array($data)){
			$content .= 'return ' . var_export($data,true) . ";\n?>";
		}else{
			$content .= "return '{$data}';\n?>";
		}
		
		$res = self::write($cacheFile, $content);
		if ($filter){
		    $content = php_strip_whitespace($cacheFile);
		    $res = self::write($cacheFile, $content);
		}
		
		return $res;
	}
	
	//获取手机号
	static public function get_tel(){
		if (isset($_SERVER['HTTP_X_UP_CALLING_LINE_ID'])) {
			return $_SERVER['HTTP_X_UP_CALLING_LINE_ID'];
		}elseif (isset($_SERVER['HTTP_X_UP_SUBNO'])) {
			$str3 = $_SERVER['HTTP_X_UP_SUBNO'];
			return preg_replace('/(.*)(11[d]{ 9 })(.*)/i','2',$str3);
		}elseif (isset($_SERVER['DEVICEID'])) {
			return $_SERVER['DEVICEID'];
		}else {
			return null;
		}
	}
	
	//获取客户端IP地址
	static public function get_ip(){
	   if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'))
	       $ip = getenv('HTTP_CLIENT_IP');
	   elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'))
	       $ip = getenv('HTTP_X_FORWARDED_FOR');
	   elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'))
	       $ip = getenv('REMOTE_ADDR');
	   elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'))
	       $ip = $_SERVER['REMOTE_ADDR'];
	   else
	       $ip = 'unknown';
	   return $ip;
	}
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name L
	 * +------------------------------------------------------------+
	 * 获取或设置语言信息，支持二维数组
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param mixed $name  键，若该值为一个数组，表示导入语言包，同框架自带的语言包进行合并
	 * @param mixed $value 该值不为null表示设置语言信息，否则获取语言信息
	 *
	 */
	static public function L($name='', $value=null){
		static $langs = array();
		!empty($langs) or $langs = require_once __LANG_PATH__ . self::_L() . '.php';
		if(is_array($name)){
			$langs = $name + $langs;
			return;
		}
		if(empty($name)) return $langs;
		false!==strpos($name,'.') && $name = explode('.',$name);
		
		if ($value===null)
			return is_array($name) ? $langs[$name[0]][$name[1]] : $langs[$name];
		else 
			is_array($name) ? $langs[$name[0]][$name[1]] = $value : $langs[$name] = $value;
	}
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name import
	 * +------------------------------------------------------------+
	 * 引入文件
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param string $file文件名，其中文件名中的“:”会被替换成“.”，“.”会替换成“/”
	 * @param string $ext 默认文件名
	 * @param path $root  根目录路径，默认为ROOT_PATH
	 *
	 */
	static public function import($file, $root=null ,$ext='.php'){
		$root = $root === null ? ROOT_PATH : $root;
		$file = str_replace(array('.', ':'), array(DIRECTORY_SEPARATOR, '.'), $file);
		require_once $root.$file.$ext;
	}
	
	///获取当前使用的语言包类型
	static private function _L(){
		defined('APP_LANG') or define('APP_LANG','zh-cn');
		switch (strtolower(APP_LANG)){
			case 'zh'://繁体
				$lang = 'zh';
				break;
			case 'en'://英文
				$lang = 'en';
				break;
			default://中文简体
				$lang = 'zh-cn';
		}
		return $lang;
	}
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name mkdir
	 * +------------------------------------------------------------+
	 * 创建目录，支持创建多级目录
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param string $pathname 目录名
	 * @param int $mode	目录读写权限
	 *
	 */
	static public function mkdir($pathname, $mode=0755){
		if (is_dir($pathname)) {
			return true;
		}
		mkdir($pathname, $mode ,true);
	}
	
	private static $_images_exts = array('bmp','jpg','jpeg','png','gif');
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name recurdir
	 * +------------------------------------------------------------+
	 * 遍历指定目录下的所有文件，并返回所匹配的文件信息
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param dir $thedir 要遍历的目录
	 * @param string $ext 要遍历的文件后缀，支持多个，用英文格式逗号进行分割，如：php,html（注：空或“*”表示不限制）
	 * @param string $regex 匹配文件名的正则表达式，默认为空
	 * @param boolean $init 遍历前是否进行初始化
	 * 
	 * @return array 一个二维数组
	 *
	 */
	static public function recurdir($thedir, $ext='php', $regex='', $init=false, $limit = 0){
		static $_types =  null, $files = null, $root = null, $file_num = 0;
		if($init){
			$_types = $files = null;
			$file_num = 0;
		}
		$root = $root === null ? $thedir : $root;
		if (!empty($ext) && empty($_types) && $ext!='*') $_types = explode(',', strtolower($ext));
		$thedir = str_replace('\\','/',$thedir);
		if(substr($thedir,-1)!='/') $thedir .= '/';
		try {
			if(!is_dir($thedir)) 
				throw new E(self::L('FUNC_R_READ_ERROR').':'.$thedir);
			if ($dir = opendir($thedir)){
				while (false !== ($anitem = readdir($dir))){
					if($anitem != '.' && $anitem != '..'){
						if (is_dir($thedir.$anitem)){//递归遍历子目录
							self::recurdir ($thedir.$anitem,$ext,$regex);
						}elseif (is_file($thedir.$anitem)){
							if ($limit > 0 && $file_num >= $limit){
								break;
							}
							
							$info = pathinfo($thedir.$anitem);
			                $filetype = strtolower($info['extension']);
			                if(!empty($regex)){
			                	//进行文件名正则匹配
			                	if(!preg_match($regex,$info['basename'])) continue;
			                }
			                if (empty($_types)){
			                	$files[] = array(
			                		'filename' => auto_charset($info['filename']),//文件名，不包含文件后缀
			                		'name' => auto_charset($info['basename']),    //文件名，有包含文件后缀
			                		'type' => $filetype,            //文件类型
			                		'dir'  => $info['dirname'],     //文件存放路径
			                		'relpath' => substr($info['dirname'], strlen($root)) . '/' . auto_charset($info['basename']),
			                		'is_image' => in_array($filetype, self::$_images_exts)
			                	);
			                	$file_num++;
			                }else{//过滤不符合扩展名的文件
		                		if(in_array($filetype,$_types)){
		                			$files[] = array(
			                			'filename' => auto_charset($info['filename']),
			                			'name' => auto_charset($info['basename']), 
			                			'type' => $filetype,
			                			'dir'  => $info['dirname'],
		                				'relpath' => substr($info['dirname'], strlen($root)) . '/' . auto_charset($info['basename']),
		                				'is_image' => in_array($filetype, self::$_images_exts)
			                		);
		                			$file_num++;
		                		}
			                }
			                unset($info,$filetype);
						}
					}
				}
			}else{
				throw new E(self::L('FUNC_OPEN_ERROR').':'.$thedir);
			}
		}catch(E $e){
			$e->getMsg();
		}
		return $files;
	}
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name redirect
	 * +------------------------------------------------------------+
	 * url重定向
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param string $url 重定向地址
	 * @param int $time   延迟时间，单位秒
	 * @param string $msg 显示信息
	 *
	 */
	static public function redirect($url, $time=0, $msg=''){
	    $url = str_replace(array("\n", "\r"), '', $url);//多行URL地址支持
	    if (!headers_sent()) {//检查标头是否已被发送以及在哪里被发送
	        header("Content-Type:text/html; charset=".OUT_CHARSET);
	        if(0===$time) {//马上跳转
	            header("Location: ".$url);
	        }else {
	            header('refresh:'.$time.';url='.$url);
	            echo "<h2 style='text-align:center;margin-top:50px;'>$msg</h2>";
	        }
	    }else {
	        $str = '<meta http-equiv="Refresh" content="'.$time.';URL='.$url.'">';
	        echo $str;
	        if ($time > 0){
	        	 dump($msg);
	        }
	    }
	    exit();
	}
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name repeat
	 * +------------------------------------------------------------+
	 * 生成一个由$num个$mark元素组成的数组
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param string $mark
	 * @param int $num
	 * @param boolean $string 是否转化成由“,”隔开的字符串
	 *
	 */
	static public function repeat($mark,$num,$string=false,$glue=','){
		$num = (int) $num;
		if($num<=0) return $string ? '' :  array();
		for($i=0;$i<$num;$i++)
			$repeat[] = $mark;
		return $string ? implode($glue, $repeat) : $repeat;
	}
	
	/**
	 * 框架内置URL重写
	 * 
	 * @param string $a
	 * @param string $m
	 * @param mixed $param
	 */
	static public function rewrite($a,$m=null,$param=null){
		if($m){
			$GLOBALS['MODULE_NAME'] = $m;
		}
		$GLOBALS['ACTION_NAME'] = $a;
		if (!empty($param)){
			if (is_string($param)){
				$param = explode('&', $param);
				foreach ($param as $v){
					$v = trim($v);
					if (empty($v)) continue;
					$v = explode('=', $v);
					$_GET[$v[0]] = $v[1];
				}
			}else{
				foreach ($param as $k=>$v) $_GET[$k] = $v;
			}
		}
		self::_running($a,$m);
		exit;
	}
	
	///执行项目
	static public function _running($act=null, $mod=null){
		$mod = empty($mod) ? $GLOBALS['MODULE_NAME'] : $mod;
		$cls = $mod . ACTION_SUFFIX;
		if(!class_exists($cls)){
			$um = C('UNDEFINE_MODULE');
			empty($um) or $cls = $um . ACTION_SUFFIX;
		}
		class_exists($cls) or E::halt(Helper::L('FUNC_R_MOD_EXISTS') . ' : ' . H($cls));
		$act = empty($act) ? $GLOBALS['ACTION_NAME'] : $act;
		$controller = new $cls;
		method_exists($controller, $act) or C('UNDEFINE_ACTION') and $act = C('UNDEFINE_ACTION');
		$controller->$act();
		//自动显示模板
		if(C('AUTO_DISPLAY',false) == true){
			$controller->_auto_display($mod . ':' . $act);
		}
	}
	
	//发送状态码
	static public function send_status($code = '200'){
		static $_status = array(
	        200 => 'OK',
	        301 => 'Moved Permanently',
	        302 => 'Moved Temporarily ',
	        400 => 'Bad Request',
	        403 => 'Forbidden',
	        404 => 'Not Found',
	        500 => 'Internal Server Error',
	        503 => 'Service Unavailable',
	    );
	    if(isset($_status[$code])) {
	        header('HTTP/1.1 ' . $code . ' ' . $_status[$code]);
	        header('Status:' . $code . ' ' . $_status[$code]);
	    }
	}
	
	/**
	 * 
	 * +------------------------------------------------------------+
	 * @name write
	 * +------------------------------------------------------------+
	 * 将数据写入指定文件，支持数组格式
	 * +------------------------------------------------------------+
	 *
	 * @author anzai <236049524@qq.com>
	 * @version 1.0
	 *
	 * @example
	 *
	 * @param string $filename 文件名
	 * @param mixed $data	数据，支持数组
	 * @param string $mode	写入模式，默认w
	 * @param int $length	写入长度
	 *
	 */
	static public function write($filename, $data, $mode='w', $length = ''){
		$dir = dirname($filename);
		is_dir($dir) or self::mkdir($dir);
		
		if(is_array($data)){
			$data = '<?php' . "\n/" . '/created time：' . date('Y-m-d H:i:s') . "\n" . 'defined("APP_NAME") or exit(\'No permission resources.\');'."\n" . 'return ' . preg_replace('/\s+/', ' ', str_replace("\n", '', var_export($data, true))) . ";\n?>";
			return file_put_contents($filename, $data);
		}else{
			try{
				$fp = fopen($filename, $mode);
				$length = (int) $length;
				$w = $length>0 ? fwrite($fp, $data, $length) : fwrite($fp, $data);
				if ($w === false) throw new E(Helper::L('CLS_HELPER_WRITE') . ' : ' . $filename);
				fclose($fp);
			}catch (E $e){
				$e->getMsg(Helper::L('FUNC_W_EXP') . ' : ' . $e->getMessage());
			}
			return true;
		}
	}
}

?>